package com.tencent.wxcloudrun.util;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.tencent.wxcloudrun.config.CustomException;
import com.tencent.wxcloudrun.config.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Component
public class PayUtils {

    @Value("${pay.envId}")
    private String envId;

    @Value("${pay.serviceName}")
    private String serviceName;

    @Value("${pay.callbackPath}")
    private String callbackPath;

    @Value("${pay.subMchId}")
    private String subMchId;

    @Value("${pay.desc}")
    private String desc;

    @Value("${pay.tradeType}")
    private String tradeType;

    @Value("${pay.unifiedOrderUrl}")
    private String unifiedOrderUrl;

    /**
     * 统一下单  调用这个接口后，服务端与微信支付都将知道一个具体的用户将需要为 tradeNo 这个订单支付 fee 分钱。
     *
     * @param fee     要支付 fee 分钱
     * @param tradeNo 要支付的订单的订单号
     * @param request 本次请求的请求信息，要从这里面提取用户的IP信息的
     * @return 返回的这个对象中的数据可以直接拿来调用 wx.requestPayment 方法
     */
    public JSONObject unifiedOrder(Integer fee, String tradeNo, HttpServletRequest request) {
        JSONObject object = new JSONObject();
        object.put("callback_type", 2);
        object.put("env_id", envId);
        object.put("function_name", callbackPath);
        object.put("sub_mch_id", subMchId);
        object.put("nonce_str", IdUtil.getSnowflakeNextIdStr());
        object.put("body", desc);
        object.put("out_trade_no", tradeNo);
        object.put("total_fee", fee);
        object.put("spbill_create_ip", getClientIp(request));
        object.put("trade_type", tradeType);
        object.put("openid", UserContext.getOpenId());
        JSONObject container = new JSONObject();
        container.put("service", serviceName);
        container.put("path", callbackPath);
        object.put("container", container);
        String req = JSON.toJSONString(object);
        log.info(">>>>请求统一下单支付的入参是 " + req);
        String resp = HttpUtil.createPost(unifiedOrderUrl).body(req).execute().body();
        log.info(">>>>请求统一下单支付的出参是 " + resp);
        // 检查是否出现错误了，反正只要有错误，就提示让用户进行线下付款即可
        if (!"ok".equals(JSON.parseObject(resp).getString("errmsg")) ||
                !"SUCCESS".equals(JSON.parseObject(resp).getJSONObject("respdata").getString("return_code")) ||
                StrUtil.isNotBlank(JSON.parseObject(resp).getJSONObject("respdata").getString("err_code"))) {
            throw new CustomException("调用统一下单接口失败，请线下支付！");
        }
        return JSON.parseObject(resp).getJSONObject("respdata").getJSONObject("payment");
    }

    /**
     * 获取调用微信支付API的机器IP
     */
    public String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Original-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        } else {
            ip = ip.split(",")[0].trim();
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }
}
